/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.core; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.beans.*; import java.io.*; import java.net.URL; import java.util.*; import javax.swing.JFileChooser; import javax.swing.AbstractAction; import org.openide.*; import org.openide.loaders.*; import org.openide.modules.*; import org.openide.options.*; import org.openide.filesystems.*; import org.openide.actions.*; import org.openide.util.actions.*; import org.openide.util.datatransfer.*; import org.openide.nodes.*; import org.openide.util.NbBundle; import org.openide.util.HelpCtx; import org.netbeans.core.windows.WindowManagerImpl; /** Node representing modules */ public class ModuleNode extends AbstractNode { private static final ResourceBundle bundle = NbBundle.getBundle( ModuleNode.class ); /** Icon bases */ private static final String MODULE_ITEM_ICON_BASE="/org/netbeans/core/resources/moduleItem"; // NOI18N // private static final String MODULE_ITEM_DISABLED_BASE="/org/netbeans/core/resources/moduleItemDisabled"; // NOI18N private static final String MODULE_TEST_ITEM_ICON_BASE="/org/netbeans/core/resources/testModuleItem"; // NOI18N private static final String MODULES_ICON_BASE="/org/netbeans/core/resources/modules"; // NOI18N /** Last directory used by the install new module file chooser. */ private static File lastChosenDir = null; /** New types */ private static NewType[] newTypes = null; /** Creates a new ModulesNode */ public ModuleNode() { super(new Modules ()); setName(Main.getString("CTL_Modules_name")); setShortDescription (Main.getString ("CTL_Modules_hint")); setIconBase (MODULES_ICON_BASE); } public HelpCtx getHelpCtx () { return new HelpCtx (ModuleNode.class); } public Node cloneNode () { return new ModuleNode (); } protected SystemAction[] createActions () { return new SystemAction[] { /* SystemAction.get (AutoLoadModulesAction.class), null, */ SystemAction.get (NewAction.class) }; } /** Add a sorting property. */ protected Sheet createSheet () { Sheet.Set set = new Sheet.Set (); set.setName ("sorting"); // NOI18N set.setDisplayName (bundle.getString ("LBL_ModuleNode_sheet_sorting")); set.put (((Modules) getChildren ()).createSortingProperty ()); Sheet sheet = new Sheet (); sheet.put (set); return sheet; } public NewType[] getNewTypes () { if ( newTypes == null ) { newTypes = new NewType[ Boolean.getBoolean ("netbeans.module.test") ? 2 : 1 ]; // NOI18N newTypes[0] = new NewType () { public String getName () { return Main.getString ("CTL_NewModuleByFile"); } public void create () throws IOException { addFile (); } }; if ( Boolean.getBoolean ("netbeans.module.test")) { // NOI18N newTypes[1] = new NewType () { public String getName () { return Main.getString( "CTL_NewTestModule"); } public void create () throws IOException { TestModuleItem.createNew(); } }; } } return newTypes; /* Old menu item new NewType () { public String getName () { return Main.getString ("CTL_NewModuleByURL"); } public void create () throws IOException { addURL (); } } */ } /** Allows to add new module by specifying its URL. */ /* void addURL () throws IOException { // PENDING - should be implemented by browser NotifyDescriptor.InputLine nd = new NotifyDescriptor.InputLine (Main.getString ("CTL_ModuleURL"), Main.getString ("CTL_AddModule")); if (TopManager.getDefault ().notify (nd) == NotifyDescriptor.OK_OPTION) { // ok URL url = new URL (nd.getInputText ()); ModuleInstaller.addModule (url); } } */ /** Allows to add new module by specifying its file. */ void addFile () throws IOException { final JFileChooser chooser = new JFileChooser (); if (lastChosenDir != null) chooser.setCurrentDirectory (lastChosenDir); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); chooser.setApproveButtonText (Main.getString ("CTL_ModuleSelect")); chooser.setApproveButtonToolTipText (Main.getString ("CTL_ModuleSelectToolTip")); chooser.setFileFilter (new javax.swing.filechooser.FileFilter () { public String getDescription () { return Main.getString ("CTL_ModuleSelectFilter"); } public boolean accept (File f) { return f.isDirectory () || f.getName ().endsWith (".jar"); // NOI18N } }); int result = chooser.showOpenDialog (WindowManagerImpl.mainWindow ()); lastChosenDir = chooser.getCurrentDirectory (); if (result == JFileChooser.APPROVE_OPTION) { // install the file //URL u = chooser.getSelectedFile ().toURL (); ModuleInstaller.installFromFile ( chooser.getSelectedFile() ); } } /** Class representing node of one standard module */ static class Item extends AbstractNode { protected ModuleItem item; public Item (ModuleItem item) { super (Children.LEAF); this.item = item; ModuleDescription moduleDesc = item.getDescription (); setName (moduleDesc.getName ()); setIconBase ( MODULE_ITEM_ICON_BASE ); //setIconBase (item.isEnabled() ? MODULE_ITEM_ICON_BASE : MODULE_ITEM_DISABLED_BASE ); setDefaultAction (SystemAction.get (PropertiesAction.class)); } public HelpCtx getHelpCtx () { String id = (String) Help.getDefault ().getHomesByCode ().get (item.getDescription ().getCodeName ()); if (id != null && item.isEnabled ()) return new HelpCtx (id); else return new HelpCtx (Item.class); } // [PENDING - properties, short description] public void destroy () { Collection depModules = ModuleInstaller.getDependentModules( item ); if ( depModules.size() > 0 ) { StringBuffer sb = new StringBuffer( 200 ); sb.append( bundle.getString( "MSG_UninstallOthers" ) ).append( "\n" ); Iterator it = depModules.iterator(); while( it.hasNext() ) { sb.append( ((ModuleItem)it.next()).getDescription().getCodeNameBase() ); sb.append( "\n" ); // NOI18N } NotifyDescriptor nd = new NotifyDescriptor.Confirmation( sb.toString(), NotifyDescriptor.OK_CANCEL_OPTION ); TopManager.getDefault().notify( nd ); if ( nd.getValue() == DialogDescriptor.CANCEL_OPTION ) return; else { it = depModules.iterator(); while( it.hasNext() ) { ModuleInstaller.deleteModule( (ModuleItem)it.next() ); } } } ModuleInstaller.deleteModule( item ); } public boolean canDestroy () { return item.canDestroy(); } /** Creates properties. */ protected Sheet createSheet () { Sheet s = Sheet.createDefault (); Sheet.Set ss = s.get (Sheet.PROPERTIES); Sheet.Set sse = Sheet.createExpertSet (); s.put(sse); try { PropertySupport p; p = new PropertySupport.ReadOnly ( "name", // NOI18N String.class, Main.getString ("PROP_modules_name"), Main.getString ("HINT_modules_name") ) { public Object getValue () { return item.getDescription ().getName (); } }; ss.put (p); p = new PropertySupport.ReadWrite ( "enabled", // NOI18N Boolean.TYPE, Main.getString ("PROP_modules_enabled"), Main.getString ("HINT_modules_enabled") ) { public Object getValue () { return new Boolean (item.isEnabled ()); } public void setValue (Object o) { if ( !((Boolean)o).booleanValue () ) { // Ask about other modules to disable Collection depModules = ModuleInstaller.getDependentModules( item ); if ( depModules.size() > 0 ) { StringBuffer sb = new StringBuffer( 200 ); sb.append( bundle.getString( "MSG_DisableOthers" ) ).append( "\n" ); Iterator it = depModules.iterator(); while( it.hasNext() ) { sb.append( ((ModuleItem)it.next()).getDescription().getCodeNameBase() ); sb.append( "\n" ); // NOI18N } NotifyDescriptor nd = new NotifyDescriptor.Confirmation( sb.toString(), NotifyDescriptor.OK_CANCEL_OPTION ); TopManager.getDefault().notify( nd ); if ( nd.getValue() == DialogDescriptor.CANCEL_OPTION ) return; else { it = depModules.iterator(); while( it.hasNext() ) { ((ModuleItem)it.next() ).setEnabled( false ); } } } } else { // Test if some other modules should be enabled if ( ModuleInstaller.resolveOrdering (Collections.nCopies (1, item), ModuleInstallerSupport.ENABLED_MODULE | ModuleInstallerSupport.DISABLED_MODULE, true ).isEmpty () ) { NotifyDescriptor.Message nd = new NotifyDescriptor.Message( bundle.getString( "MSG_Module_Missed_Enabled" ) + "\n" + ModuleInstaller.getMissed( ModuleInstallerSupport.ENABLED_MODULE | ModuleInstallerSupport.DISABLED_MODULE, Collections.nCopies (1, item) ) ); TopManager.getDefault().notify( nd ); return; } Collection orderedModules = ModuleInstaller.checkDependenciesOnDisabled ( item.getDescription() ); if ( orderedModules != null ) { Iterator it = orderedModules.iterator(); while( it.hasNext() ) { ((ModuleItem)it.next() ).setEnabled( true ); } } else return; } item.setEnabled (((Boolean)o).booleanValue ()); // setIconBase (item.isEnabled() ? MODULE_ITEM_ICON_BASE : MODULE_ITEM_DISABLED_BASE ); } }; ss.put (p); p = new PropertySupport.ReadOnly ( "specVersion", // NOI18N String.class, Main.getString ("PROP_modules_specversion"), Main.getString ("HINT_modules_specversion") ) { public Object getValue () { return item.getDescription ().getSpecVersion (); } }; ss.put (p); p = new PropertySupport.ReadOnly ( "implVersion", // NOI18N String.class, Main.getString ("PROP_modules_implversion"), Main.getString ("HINT_modules_implversion") ) { public Object getValue () { return item.getDescription ().getImplVersion (); } }; ss.put (p); p = new PropertySupport.ReadOnly ( "codeName", // NOI18N String.class, Main.getString ("PROP_modules_codename"), Main.getString ("HINT_modules_codename") ) { public Object getValue () { return item.getDescription ().getCodeName (); } }; sse.put (p); p = new PropertySupport.ReadOnly ( "url", // NOI18N java.net.URL.class, Main.getString ("PROP_modules_url"), Main.getString ("HINT_modules_url") ) { public Object getValue () { return item.getLoaderURL (); } }; sse.put (p); } catch (Exception e) { e.printStackTrace (); throw new InternalError (); } return s; } } /** Class rerpesenting a testmodule */ static class TestItem extends Item { private static final SystemAction[] SYSTEM_ACTIONS = new SystemAction[] { SystemAction.get( ReinstallTestModuleAction.class ), SystemAction.get( PropertiesAction.class) }; public TestItem (TestModuleItem item) { super( item ); this.item = item; customizeSheet(); ModuleDescription moduleDesc = item.getDescription (); setName (moduleDesc.getName ()); setIconBase (MODULE_TEST_ITEM_ICON_BASE); } public Node.Cookie getCookie( Class clazz ) { if ( clazz == TestModuleItem.class ) return (Node.Cookie) item; return super.getCookie( clazz ); } public SystemAction[] getActions() { return SYSTEM_ACTIONS; } void customizeSheet () { Sheet.Set ss = getSheet().get (Sheet.PROPERTIES); ss.remove( "enabled" ); // NOI18N PropertySupport p = new PropertySupport.ReadOnly ( "enabled", // NOI18N Boolean.TYPE, Main.getString ("PROP_modules_enabled"), Main.getString ("HINT_modules_enabled") ) { public Object getValue () { //return new Boolean ( item.isEnabled ()); return new Boolean ( true ); } }; ss.put (p); } } /** Children that contains modules installed it has to * dissingushg between modules and test modules. */ private static class Modules extends Children.Keys implements PropertyChangeListener { /** sorting style * preferably would be stored permanently somewhere but there is nowhere good to store it */ private int sortedModuleList = SORT_UNSORTED; private static final int SORT_UNSORTED = 0; private static final int SORT_DISPLAYNAME = 1; private static final int SORT_CODENAME = 2; private static final int SORT_ENABLED = 3; private static final int SORT_URL = 4; /** Refreshed list of nodes acc. to current sorting and contents. */ private void refreshKeys () { ModuleItem[] items = ModuleInstaller.getModuleItems ( ModuleInstallerSupport.ENABLED_MODULE | ModuleInstallerSupport.DISABLED_MODULE | ModuleInstallerSupport.TEST_MODULE ); if (sortedModuleList != SORT_UNSORTED) { items = (ModuleItem[]) items.clone (); Arrays.sort (items, new Comparator () { public int compare (Object o1, Object o2) { ModuleItem m1 = (ModuleItem) o1; ModuleItem m2 = (ModuleItem) o2; switch (sortedModuleList) { case SORT_CODENAME: return m1.getDescription ().getCodeName ().compareTo (m2.getDescription ().getCodeName ()); case SORT_ENABLED: if (m1.isEnabled () && ! m2.isEnabled ()) return -1; if (! m1.isEnabled () && m2.isEnabled ()) return 1; if ((m1 instanceof TestModuleItem) && ! (m2 instanceof TestModuleItem)) return 1; if (! (m1 instanceof TestModuleItem) && (m2 instanceof TestModuleItem)) return -1; // fallthrough case SORT_DISPLAYNAME: return m1.getDescription ().getName ().compareTo (m2.getDescription ().getName ()); case SORT_URL: if ((m1 instanceof TestModuleItem) && ! (m2 instanceof TestModuleItem)) return 1; if (! (m1 instanceof TestModuleItem) && (m2 instanceof TestModuleItem)) return -1; if ((m1 instanceof TestModuleItem) && (m2 instanceof TestModuleItem)) return 0; return m1.getLoaderURL ().toString ().compareTo (m2.getLoaderURL ().toString ()); default: return 0; } } }); } setKeys (items); } Node.Property createSortingProperty () { return new PropertySupport.ReadWrite ("sorted", Integer.TYPE, // NOI18N bundle.getString ("PROP_ModuleNode_sorted"), bundle.getString ("HINT_ModuleNode_sorted")) { public Object getValue () { return new Integer (sortedModuleList); } public void setValue (Object o) { sortedModuleList = ((Integer) o).intValue (); refreshKeys (); } public boolean supportsDefaultValue () { return true; } public void restoreDefaultValue () { setValue (new Integer (SORT_UNSORTED)); } public PropertyEditor getPropertyEditor () { return new PropertyEditorSupport () { private final String[] tags = new String[] { bundle.getString ("LBL_ModuleNode_SORT_UNSORTED"), bundle.getString ("LBL_ModuleNode_SORT_DISPLAYNAME"), bundle.getString ("LBL_ModuleNode_SORT_CODENAME"), bundle.getString ("LBL_ModuleNode_SORT_ENABLED"), bundle.getString ("LBL_ModuleNode_SORT_URL"), }; public String[] getTags () { return tags; } public String getAsText () { return tags[((Integer) this.getValue ()).intValue ()]; } public void setAsText (String text) { for (int i = 0; i < tags.length; i++) { if (tags[i].equals (text)) { this.setValue (new Integer (i)); return; } } throw new IllegalArgumentException (); } }; } }; } /** Initializes content */ public void addNotify () { ModuleInstaller.addPropertyChangeListener (this); refreshKeys (); } /** Releases listener. */ public void removeNotify () { ModuleInstaller.removePropertyChangeListener (this); } /** Reacts to changes */ public void propertyChange (PropertyChangeEvent ev) { refreshKeys (); } /** Generates node for the ModuleItem key */ protected Node[] createNodes (Object key) { if ( key instanceof TestModuleItem ) { Node[] nodes = new Node[] { new TestItem ((TestModuleItem)key) }; return nodes; } else return new Node[] { new Item ((ModuleItem)key) }; } } /** Action that refreshes the modules in the modules directory. */ public static final class AutoLoadModulesAction extends CallableSystemAction { static final long serialVersionUID =-6598195161786990764L; public String getName () { return Main.getString ("CTL_AutoLoadModules"); } public HelpCtx getHelpCtx () { return new HelpCtx (AutoLoadModulesAction.class); } public void performAction () { ModuleInstaller.autoLoadModules (); } } /** Action deinstalls and installs again the test module. Used by the module developer * after compilation to test the changes. */ public static final class ReinstallTestModuleAction extends CookieAction { private static final Class[] cookieClasses = new Class[] { TestModuleItem.class }; static final long serialVersionUID =7167727704611723438L; public String getName () { return Main.getString ("CTL_ReinstallTestModule"); } public HelpCtx getHelpCtx () { return new HelpCtx (ReinstallTestModuleAction.class); } protected Class[] cookieClasses() { return cookieClasses; } protected boolean enable( Node[] nodes ) { return true; } protected int mode() { return CookieAction.MODE_ALL; } public void performAction ( Node activatedNodes[] ) { for ( int i = 0; i < activatedNodes.length; i++ ) { TestModuleItem item = (TestModuleItem)activatedNodes[i].getCookie( TestModuleItem.class ); item.reinstall(); } //ModuleInstaller.autoLoadModules (); } } } /* * Log * 22 Gandalf 1.21 1/13/00 Jaroslav Tulach I18N * 21 Gandalf 1.20 1/7/00 Petr Hrebejk Messages added to * enabling modules and installing from file * 20 Gandalf 1.19 1/5/00 Petr Hrebejk New module installer * 19 Gandalf 1.18 12/22/99 Jesse Glick Better module sorting. * 18 Gandalf 1.17 12/21/99 Jesse Glick Module list may now be * sorted, optionally. * 17 Gandalf 1.16 11/26/99 Patrik Knakal * 16 Gandalf 1.15 11/10/99 Petr Hrebejk Unistalling/Disabling of * module now Uninstalls/Disables all dependent modules * 15 Gandalf 1.14 10/27/99 Petr Hrebejk Testing of modules added * 14 Gandalf 1.13 10/24/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems copyright in file comment * 13 Gandalf 1.12 10/18/99 Jesse Glick Minor usability * improvements--PropertiesAction default on item nodes; file chooser * always stores current dir. * 12 Gandalf 1.11 9/30/99 Jesse Glick Brief log messages re. * module installation and uninstallation, for tech support purposes. Also * improved file chooser for New from File. * 11 Gandalf 1.10 8/18/99 Ian Formanek Generated serial version * UID * 10 Gandalf 1.9 7/12/99 Jaroslav Tulach To be compilable. * 9 Gandalf 1.8 7/9/99 Jesse Glick Better context help. * 8 Gandalf 1.7 7/8/99 Jesse Glick Context help. * 7 Gandalf 1.6 7/2/99 Jaroslav Tulach Enabled add module from * file * 6 Gandalf 1.5 6/24/99 Jesse Glick Gosh-honest HelpID's. * 5 Gandalf 1.4 6/8/99 Ian Formanek ---- Package Change To * org.openide ---- * 4 Gandalf 1.3 6/8/99 Petr Hrebejk Node PoupMenu disabled * 3 Gandalf 1.2 5/27/99 Jaroslav Tulach auto load of modules. * 2 Gandalf 1.1 5/8/99 Ian Formanek Improved ModuleNode * properties * 1 Gandalf 1.0 4/28/99 Jaroslav Tulach * $ */